Add timestamp option to xenconsoled
authorKeir Fraser <keir.fraser@citrix.com>
Tue, 12 Feb 2008 10:16:20 +0000 (10:16 +0000)
committerKeir Fraser <keir.fraser@citrix.com>
Tue, 12 Feb 2008 10:16:20 +0000 (10:16 +0000)
Similar to the --log option, --timestamp or -t takes:
- none : No timestamping
- hv   : Timestamp hypervisor logs
- guest: Timestamp guest logs
- all  : Timestamp guest and hypervisor logs

From: Cole Robinson <crobinso@redhat.com>
Signed-off-by: Keir Fraser <keir.fraser@citrix.com>
tools/console/daemon/io.c
tools/console/daemon/main.c

index 735a77b0e6481beb0af04a2a32f1d8e524511746..52df19ed34cfd7bb665bc38edc2ab0bae8a97569 100644 (file)
@@ -60,6 +60,8 @@
 extern int log_reload;
 extern int log_guest;
 extern int log_hv;
+extern int log_time_hv;
+extern int log_time_guest;
 extern char *log_dir;
 
 static int log_hv_fd = -1;
@@ -99,6 +101,50 @@ struct domain
 
 static struct domain *dom_head;
 
+static int write_all(int fd, const char* buf, size_t len)
+{
+       while (len) {
+               ssize_t ret = write(fd, buf, len);
+               if (ret == -1 && errno == EINTR)
+                       continue;
+               if (ret <= 0)
+                       return -1;
+               len -= ret;
+               buf += ret;
+       }
+
+       return 0;
+}
+
+static int write_with_timestamp(int fd, const char *data, size_t sz)
+{
+       char buf[sz+1];
+       char ts[32];
+       time_t now = time(NULL);
+       const struct tm *tmnow = localtime(&now);
+       size_t tslen = strftime(ts, sizeof(ts), "[%d-%m-%Y %H:%M:%S] ", tmnow);
+
+       memcpy(buf, data, sz);
+       while (sz > 0 && buf[sz-1] == '\r')
+               sz--;               // Don't print trailing \r's
+       if (sz > 0 && buf[sz-1] != '\n')
+               buf[sz++] = '\n';   // Force ending newline
+       data = buf;
+
+       while (sz > 0) {
+               const char *nl = strchr(data, '\n') + 1;
+               size_t towrite = nl - data;
+               if (write_all(fd, ts, tslen) < 0)
+                       return -1;
+               if (write_all(fd, data, towrite))
+                       return -1;
+               sz -= towrite;
+               data = nl;
+       }
+
+       return 0;
+}
+
 static void buffer_append(struct domain *dom)
 {
        struct buffer *buffer = &dom->buffer;
@@ -135,10 +181,13 @@ static void buffer_append(struct domain *dom)
         * and handle_tty_write will stop being called.
         */
        if (dom->log_fd != -1) {
-               int len = write(dom->log_fd,
-                               buffer->data + buffer->size - size,
-                               size);
-               if (len < 0)
+               int logret;
+               if (log_time_guest) {
+                       logret = write_with_timestamp(dom->log_fd, buffer->data + buffer->size - size, size);
+               } else {
+                       logret = write_all(dom->log_fd, buffer->data + buffer->size - size, size);
+        }
+               if (logret < 0)
                        dolog(LOG_ERR, "Write to log failed on domain %d: %d (%s)\n",
                              dom->domid, errno, strerror(errno));
        }
@@ -195,6 +244,15 @@ static int create_hv_log(void)
        if (fd == -1)
                dolog(LOG_ERR, "Failed to open log %s: %d (%s)",
                      logfile, errno, strerror(errno));
+       if (fd != -1 && log_time_hv) {
+               if (write_with_timestamp(fd, "Logfile Opened",
+                                        strlen("Logfile Opened")) < 0) {
+                       dolog(LOG_ERR, "Failed to log opening timestamp "
+                                      "in %s: %d (%s)", logfile, errno,
+                                      strerror(errno));
+                       return -1;
+               }
+       }
        return fd;
 }
 
@@ -229,6 +287,15 @@ static int create_domain_log(struct domain *dom)
        if (fd == -1)
                dolog(LOG_ERR, "Failed to open log %s: %d (%s)",
                      logfile, errno, strerror(errno));
+       if (fd != -1 && log_time_guest) {
+               if (write_with_timestamp(fd, "Logfile Opened",
+                                        strlen("Logfile Opened")) < 0) {
+                       dolog(LOG_ERR, "Failed to log opening timestamp "
+                                      "in %s: %d (%s)", logfile, errno,
+                                      strerror(errno));
+                       return -1;
+               }
+       }
        return fd;
 }
 
@@ -817,11 +884,16 @@ static void handle_hv_logs(void)
        if ((port = xc_evtchn_pending(xce_handle)) == -1)
                return;
 
-       if (xc_readconsolering(xc_handle, &bufptr, &size, 0, 1, &index) == 0) {
-               int len = write(log_hv_fd, buffer, size);
-               if (len < 0)
-                       dolog(LOG_ERR, "Failed to write hypervisor log: %d (%s)",
-                             errno, strerror(errno));
+       if (xc_readconsolering(xc_handle, &bufptr, &size, 0, 1, &index) == 0 && size > 0) {
+               int logret;
+               if (log_time_guest)
+                       logret = write_with_timestamp(log_hv_fd, buffer, size);
+               else
+                       logret = write_all(log_hv_fd, buffer, size);
+
+               if (logret < 0)
+                       dolog(LOG_ERR, "Failed to write hypervisor log: "
+                                      "%d (%s)", errno, strerror(errno));
        }
 
        (void)xc_evtchn_unmask(xce_handle, port);
index ea0648f40047ac09c59b743948f177a316c171d6..c66642ff46e7f200ccaf63476a6d42498235838e 100644 (file)
@@ -35,6 +35,8 @@
 int log_reload = 0;
 int log_guest = 0;
 int log_hv = 0;
+int log_time_hv = 0;
+int log_time_guest = 0;
 char *log_dir = NULL;
 
 static void handle_hup(int sig)
@@ -44,7 +46,7 @@ static void handle_hup(int sig)
 
 static void usage(char *name)
 {
-       printf("Usage: %s [-h] [-V] [-v] [-i] [--log=none|guest|hv|all] [--log-dir=DIR] [--pid-file=PATH]\n", name);
+       printf("Usage: %s [-h] [-V] [-v] [-i] [--log=none|guest|hv|all] [--log-dir=DIR] [--pid-file=PATH] [-t, --timestamp=none|guest|hv|all]\n", name);
 }
 
 static void version(char *name)
@@ -54,7 +56,7 @@ static void version(char *name)
 
 int main(int argc, char **argv)
 {
-       const char *sopts = "hVvi";
+       const char *sopts = "hVvit:";
        struct option lopts[] = {
                { "help", 0, 0, 'h' },
                { "version", 0, 0, 'V' },
@@ -63,6 +65,7 @@ int main(int argc, char **argv)
                { "log", 1, 0, 'l' },
                { "log-dir", 1, 0, 'r' },
                { "pid-file", 1, 0, 'p' },
+               { "timestamp", 1, 0, 't' },
                { 0 },
        };
        bool is_interactive = false;
@@ -103,6 +106,19 @@ int main(int argc, char **argv)
                case 'p':
                        pidfile = strdup(optarg);
                        break;
+               case 't':
+                       if (!strcmp(optarg, "all")) {
+                               log_time_hv = 1;
+                               log_time_guest = 1;
+                       } else if (!strcmp(optarg, "hv")) {
+                               log_time_hv = 1;
+                       } else if (!strcmp(optarg, "guest")) {
+                               log_time_guest = 1;
+                       } else if (!strcmp(optarg, "none")) {
+                               log_time_guest = 0;
+                               log_time_hv = 0;
+                       }
+                       break;
                case '?':
                        fprintf(stderr,
                                "Try `%s --help' for more information\n",